iT邦幫忙

2023 iThome 鐵人賽

DAY 6
0
Modern Web

30 天淺入淺出 Next.js 13系列 第 6

Day6 - App Router - 動態路由

  • 分享至 

  • xImage
  •  

繼上一篇介紹 App Router,我們知道要怎麼在 App Router 中利用保留字建立路由及其他功能型組件,也了解了這些功能型組件是怎麼嵌套的。

接下來我們會介紹如何在 App Router 建立動態路由(dynamic router)。

動態路由

當我們事先不能預知 router 的路徑是什麼,或者我們的頁面需要保持路徑的格式不變,但頁面會根據路由中的某一段進行渲染,這時候我們就可以使用動態路。

現在你看到的鐵人賽網站就是使用動態路由做渲染的,這篇 Day6 - App Router 動態路由 文章的路徑如下:
https://ithelp.ithome.com.tw/articles/10324542

如果你點擊其他的鐵人賽文章,你會看到前面這段路徑 https://ithelp.ithome.com.tw/articles/ 還是一樣的,不過後面的路徑不是 10324542,而是其他唯一值。這個唯一值是「IT邦幫忙」自動幫我生成的,用來確保每一頁都是獨一無二的,他們可以透過這個唯一值去找到對應的文章。

基本寫法

動態路由與固定路由的寫法很像,差別是檔案名稱需要用中括號包住。

我們以建立一個「it邦幫忙」的文章動態路由為例:
建立 app/articles/[slug]/page.tsx,此時我們就建立好 /articles/[可填入任意參數] 的路由。接下來我們還需要根據 slug 參數去 fetch 文章的資料回來。我們可以從 page.tsx 的參數解構出 params 物件取得 slug 的值,注意這邊的 slug 是根據你檔案夾名稱而定,如果是 app/articles/[id]/page.tsx,那就是取 id 值。

// app/articles/[slug]/page.tsx

type Props = { 
    params: { slug: string } 
}

export default function Page({ params }: Props) {
  // fetch article here
  
  return <div>My Post: {params.slug}</div>
}

我全都要路由(Catch-all Segments)

有時我們的動態路由挖空的參數不只一個怎麼辦?假設我們還多塞了些參數,並且這些參數是被允許的,像是

  • /articles/123
  • /articles/123/is-cool
  • /articles/123/is/very/long/but/still/work

沒關係,你的煩惱,Next 知道。我們只要在檔案夾名稱加上展開運算符就可以,取得的 slug。

一樣以鐵人賽文章為例,該檔案路徑就是 app/articles/[...slug]/page.tsx,此時從 page.tsx 取得的就是一個字串陣列,以上面的路徑為例,取得的 slug 值就會是

路徑 slug值
/articles/123 ['123']
/articles/123/is-cool ['123', 'is-cool']
/articles/123/is/very/long/but/still/work ['123', 'is', 'very', 'long', 'but', 'still', 'work']

我「可能」全都要路由(Optional Catch-all Segments)

不知道大家有沒有注意到,上面的路由是不會配對到 /articles 本身,如果希望這個 page.tsx 也可以配對到 /articles,那可以使用二維展開運算 slug (名字我取的,在官網找不到)。

一樣以鐵人賽路由為例,那就會是 app/articles/[[...slug]]/page.tsx,這樣就可以連 /articles 也配對到了。

有限的靜態路由

上面還有一種情境沒有講到,那就是有限個動態路由路由的情況。

這種情況會使用 SSG 的方法來達成目的:

  1. generateStaticParams
  2. dynamicParams

還是以鐵人賽文章為例,我就只要渲染 slug 為 A, B, C 的鐵人賽文章,其他都不要渲染。

舉例:

  • articles/A: 渲染
  • articles/another: 不渲染,因為不包含在 A, B, C

我們可以在 app/articles/[slug].tsx 中 export 一個特殊的 function generateStaticParams,這個 function name 也是 Next 的保留字,代表這個頁面要使用 SSG 渲染,它會在 build time 的時候執行這個 function 取得所有已知的 slug,並提前先把頁面的 html 給組好。

再透過 dynamicParams 決定是否允許以外的路徑訪問。

generateStaticParams 也可以使用非同步的方式取得 slug,這裡為了方便就直接寫死。

// 決定允不允許非 generateStaticParams 產出的 slug 訪問
export const dynamicParams = false // true | false,

export function generateStaticParams() {
  const articles = ['A', 'B', 'C'];
 
  return posts.map((post) => ({
    slug: articles
  }))
}

關於 dynamic 結合 SSG 的寫法,後面會再提到。

後記

無力

參考資料


上一篇
Day5 - App Router - 基礎結構
下一篇
Day7 - 淺談渲染方式 CSR/SSR/SSG/ISR
系列文
30 天淺入淺出 Next.js 1321
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言